package com.thunder.reader.ui;

import java.io.FileNotFoundException;
import java.util.ArrayList;

import android.app.ListActivity;
import android.content.AsyncQueryHandler;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnCreateContextMenuListener;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.thunder.reader.R;
import com.thunder.reader.provider.Feed;
import com.thunder.reader.provider.FeedProvider;
import com.thunder.reader.transaction.Transaction;
import com.thunder.reader.transaction.TransactionService;
import com.thunder.reader.util.Utility;

public class ArticleListActivity extends ListActivity {
    private static final String TAG = "ArticleListActivity";
    private AsyncArticleQueryHandler mQueryHandler;
    private ArticleListAdapter mListAdapter;
    private Uri mSourceUri;
    private int mSourceId;
    // Handler message ids
    private static final int TOKEN_QUERY_ALL_ARTICLE = 0;
    
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
        Intent intent =  getIntent();
        mSourceUri = intent.getData();
        mSourceId = Integer.valueOf(mSourceUri.getPathSegments().get(1));
        setTitle(getSourceName(mSourceUri));
        getListView().setOnCreateContextMenuListener(mContextMenu);
        mQueryHandler = new AsyncArticleQueryHandler(getContentResolver());
        mListAdapter = new ArticleListAdapter(getApplication(), null);
        mListAdapter.addContentChangedListener(new OnContentChangedListener() {
            public void onContentChanged() {
                updateProgressState();
                startAsyncQuery(mSourceUri);
            }
        });
        setListAdapter(mListAdapter);
        startAsyncQuery(mSourceUri);
        updateThisFeed(mSourceId);
    }

    private void updateThisFeed(final long id) {
        final Uri uri = ContentUris.withAppendedId(Feed.Source.CONTENT_URI, id);
        final Intent intent = new Intent(getApplication(), TransactionService.class);
        intent.putExtra(Transaction.EXTRA_TRANSACTION_TYPE, Transaction.TRANSACTION_TYPE_UPDATE_FEED);
        intent.setData(uri);
        startService(intent);
    }

    private String getSourceName(Uri sourceUri) {
        final Cursor cursor = getContentResolver().query(sourceUri, new String[]{Feed.Source.TITLE}, null, null, null);
        String sourceName = null;
        if (cursor != null && cursor.moveToFirst()) {
            sourceName = cursor.getString(0);
        }
        if (TextUtils.isEmpty(sourceName)) {
            sourceName = getString(R.string.label_article);
        }
        return sourceName;
    }
    
    @Override
    public void onResume() {
        super.onResume();
        updateProgressState();
    }
    
    @Override
    public void onPause() {
        super.onPause();
        updateProgressState();
    }
    
    private void updateProgressState() {
        final Cursor c = getContentResolver().query(mSourceUri, 
                new String[]{Feed.Source.UPDATING}, null, null, null);
        if (c != null && c.moveToFirst()) {
            int status = c.getInt(0);
            Log.e(TAG, "what the fuck, status is " + status);
            if (status == 0) {
                setProgressOff();
            } else {
                setProgressOn();
            }
        }
        if (c != null) {
            c.close();
        }
    }

    private OnCreateContextMenuListener mContextMenu = new OnCreateContextMenuListener() {
        public void onCreateContextMenu(ContextMenu menu, View v,
                ContextMenuInfo info) {
            final Uri articleUri = ContentUris.withAppendedId(Feed.Article.CONTENT_URI, ((AdapterContextMenuInfo) info).id);
            final Cursor cursor = getContentResolver().query(articleUri, new String[]{Feed.Article.TITLE}, 
                    null, null, null);
            if (cursor == null || !cursor.moveToFirst()) {
                return;
            }
            getMenuInflater().inflate(R.menu.article_list_contextmenu, menu);
            menu.setHeaderTitle(cursor.getString(0));
            cursor.close();
        }
    };
    
    @Override
    public boolean onContextItemSelected(MenuItem item) {
        final AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
        switch (item.getItemId()) {
        case R.id.article_list_contextmenu_delete: {
            final Intent intent = new Intent(getApplication(), DeleteItemActivity.class);
            intent.putExtra(DeleteItemActivity.EXTRA_ARTICLE_ID, menuInfo.id);
            startActivity(intent);
            break;
        }
        case R.id.article_list_contextmenu_mark_as_read: {
            final ContentValues values = new ContentValues();
            values.put(Feed.Article.READ, 1);
            getContentResolver().update(ContentUris.withAppendedId(Feed.Article.CONTENT_URI, menuInfo.id), values, null, null);
            break;
        }
        case R.id.article_list_contextmenu_mark_as_unread: {
            final ContentValues values = new ContentValues();
            values.put(Feed.Article.READ, 0);
            getContentResolver().update(ContentUris.withAppendedId(Feed.Article.CONTENT_URI, menuInfo.id), values, null, null);
            break;
        }
        default:
            break;
        }
        return true;
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.article_list, menu);
        return true;
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.article_list_mark_all_as_read: {
            final ContentValues cv = new ContentValues();
            cv.put(Feed.Article.READ, 1);
            getContentResolver().update(Feed.Article.CONTENT_URI, cv, 
                    Feed.Article.SOURCE_ID + "=?", new String[]{mSourceUri.getPathSegments().get(1)});
            break;
        }
        case R.id.article_list_mark_all_as_unread: {
            final ContentValues cv = new ContentValues();
            cv.put(Feed.Article.READ, 0);
            getContentResolver().update(Feed.Article.CONTENT_URI, cv, 
                    Feed.Article.SOURCE_ID + "=?", new String[]{mSourceUri.getPathSegments().get(1)});
            break;
        }
        case R.id.article_list_delete_all: {
            getContentResolver().delete(Feed.Article.CONTENT_URI, Feed.Article.SOURCE_ID + "=?", new String[]{mSourceUri.getPathSegments().get(1)});
            break;
        }
        case R.id.article_list_update_feed: {
            final Intent intent = new Intent(getApplication(), TransactionService.class);
            intent.putExtra(Transaction.EXTRA_TRANSACTION_TYPE, Transaction.TRANSACTION_TYPE_UPDATE_FEED);
            intent.setData(mSourceUri);
            startService(intent);
            break;
        }
        default:
            break;
        }
        return true;
    }
    
    @Override
    public void onListItemClick(ListView listView, View view, int position, long id) {
        final Cursor cursor = (Cursor) listView.getItemAtPosition(position);
        final int articleId = cursor.getInt(Feed.Article.ID_INDEX);
        final Uri articleUri = ContentUris.withAppendedId(Feed.Article.CONTENT_URI, articleId);
        // mark this article as read
        final ContentValues cv = new ContentValues();
        cv.put(Feed.Article.READ, 1);
        getContentResolver().update(articleUri, cv, null, null);
        final String url = cursor.getString(Feed.Article.ARTICLE_URL_INDEX);
        if (!TextUtils.isEmpty(url)) {
            final Intent intent = ViewArticleActivity.createViewArticleIntent(getApplication(), articleUri, position, mSourceId);
            startActivity(intent);
            overridePendingTransition(R.anim.default_come_enter, R.anim.default_come_exit);
        } else {
            Log.e(TAG, "Url is emtpy, shit happens");
        }
    }
    
    @Override
    public void onBackPressed() {
	super.onBackPressed();
	overridePendingTransition(R.anim.default_leave_enter, R.anim.default_leave_exit);
    }
    
    private void startAsyncQuery(Uri sourceUri) {
        setProgressOn();
        mQueryHandler.startQuery(TOKEN_QUERY_ALL_ARTICLE, null, 
                Feed.Article.CONTENT_URI, Feed.Article.PROJECTION, Feed.Article.SOURCE_ID + "=?", 
                new String[]{sourceUri.getPathSegments().get(1)}, FeedProvider.ARTICLE_ORDER);
    }

    private void setProgressOn() {
        setProgressBarIndeterminateVisibility(true);
    }
    
    private void setProgressOff() {
        setProgressBarIndeterminateVisibility(false);
    }
    
    private final class AsyncArticleQueryHandler extends AsyncQueryHandler {
        public AsyncArticleQueryHandler(ContentResolver cr) {
            super(cr);
        }
        
        @Override
        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
            mListAdapter.changeCursor(cursor);
            setProgressOff();
        }

        
        @Override
        protected void onDeleteComplete(int token, Object cookie, int result) {
            
        }
        
        @Override
        protected void onUpdateComplete(int token, Object cookie, int result) {
            
        }
        
        @Override
        protected void onInsertComplete(int token, Object cookie, Uri uri) {
            
        }
    }
    
    private class ArticleListAdapter extends CursorAdapter {
        private LayoutInflater mFactory;
        
        private ArrayList<OnContentChangedListener> mListenerList;
        public ArticleListAdapter(Context context, Cursor c) {
            super(context, c, false);
            mFactory = LayoutInflater.from(context);
            mListenerList = new ArrayList<OnContentChangedListener>();
        }
        
        public void addContentChangedListener(OnContentChangedListener listener) {
            assert(mListenerList == null);
            mListenerList.add(listener);
        }
        
        @Override
        public void bindView(View view, Context context, Cursor cursor) {
            assert(view == null);
            TextView title = (TextView) view.findViewById(R.id.article_list_item_title);
            TextView pubDate = (TextView) view.findViewById(R.id.article_list_item_pubdate);
            TextView description = (TextView) view.findViewById(R.id.article_list_item_description);
            title.setText(cursor.getString(Feed.Article.TITLE_INDEX));
            final long date = cursor.getLong(Feed.Article.PUB_DATE_INDEX);
            pubDate.setText(Utility.dateToString(date));
            description.setText(cursor.getString(Feed.Article.DESCRIPTION_INDEX));
            final int read = cursor.getInt(Feed.Article.READ_INDEX);
            if (read == 0) {
                title.setTextColor(Color.BLUE);
            } else {
                title.setTextColor(Color.BLACK);
            }
            
            ImageView thumbnail = (ImageView) view.findViewById(R.id.article_list_item_thumbnail);
            Bitmap thumb = getThumbnail(cursor);
            if (thumb != null) {
                thumbnail.setVisibility(View.VISIBLE);
                thumbnail.setImageBitmap(thumb);
            } else {
        	thumbnail.setVisibility(View.GONE);
            }
        }
        

        private Bitmap getThumbnail(Cursor cursor) {
            Bitmap bm = null;
            String imageId = cursor.getString(Feed.Article.IMAGE_ID_INDEX);
            if (TextUtils.isEmpty(imageId)) {
                return null;
            }
            final Uri uri = ContentUris.withAppendedId(Feed.Image.CONTENT_URI, Integer.valueOf(imageId));
            try {
                bm = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
            } catch (FileNotFoundException e) {
            }
            return bm;
        }
        
        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {
            return mFactory.inflate(R.layout.article_list_item, null);
        }
        
        @Override
        protected void onContentChanged() {
            for (OnContentChangedListener listener : mListenerList) {
                listener.onContentChanged();
            }
        }
        
    }

    public interface OnContentChangedListener {
        public void onContentChanged();
    }
}